home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / develop / libsrc11.arc / AUTOSUPP.S < prev    next >
Text File  |  1989-04-27  |  6KB  |  206 lines

  1. *    /*    autosupp.s 4.2        */
  2. *
  3.     xdef    dmulu
  4. *
  5. *    dmulu    - 32 by 32 multiply giving low 32 bits of result
  6. *    This is an UNSIGNED multiply.
  7. *
  8. *    DMULU multiplies Operand 1 by Operand 2 storing the result
  9. *    in Operand 3.  The algorithm used initially sets the
  10. *    high two words of result (words 0 and 1) to zero and
  11. *    the low two words of result to Operand 1.  The multiply
  12. *    is done by seeing if the low bit of result word 3 is
  13. *    set, if it is then Operand 2 is added to result words
  14. *    0 and 1.  Then, whether the add was done or not, all
  15. *    of result is shifted right one with the most significant
  16. *    being the carry of the last add or zero if no add was
  17. *    done.  This process of checking low bit of result word 3,
  18. *    conditionally adding Operand 2, and then shifting Result
  19. *    right is repeated 32 times (shift count).
  20. *
  21. *    A clever algorithm, for it does multiplication by dividing
  22. *    by 2 (shifting right)...
  23. *
  24. *    Equates:
  25. lo    equ    2    low word of operand
  26. hi    equ    0    high word of operand
  27. *
  28. shift    equ    0    shift count
  29. res    equ    1    result
  30. reslo32    equ    5    result - low 32 bits
  31. savex    equ    9    saved x
  32. rtnPC    equ    11    return pc
  33. op3    equ    13    result returned pointer
  34. *
  35. *    Parameters:
  36. *        Operand 1 -> D register.
  37. *            This is a pointer to the multiplicand (32 bits).
  38. *        Operand 2 -> Y register.
  39. *            This is a pointer to the multiplier (32 bits).
  40. *        Operand 3 -> 1st word on stack after return PC
  41. *            This is a pointer to the low 32 bits of the product.
  42. *
  43. dmulu    pshx        save x register
  44.     xgdy        swap parameters temporarily
  45.     ldx    lo,%y    store operand 1 in result lo 32
  46.     pshx
  47.     ldx    hi,%y
  48.     pshx
  49.     ldx    #0
  50.     pshx        result word 1
  51.     pshx        result word 0
  52.     xgdy        reset parameters
  53.     ldaa    #32    shift count (clobbers operand 1--no longer needed)
  54.     psha        put shift count onto stack
  55.     tsx        set x to point to parameter/work area
  56. *
  57. *    stack register/stack/x register look like:
  58. *
  59. *    x,s    ->    shift count        0,%x    tos
  60. *        ->    result word 0        1,%x    tos+1
  61. *        ->    result word 1        3,%x    tos+3
  62. *        ->    result word 2        5,%x    tos+5
  63. *        ->    result word 3        7,%x    tos+7
  64. *        ->    saved x            9,%x    tos+9
  65. *        ->    return PC        11,%x    tos+11
  66. *        ->    op 3 ptr (result)    13,%x    tos+13
  67. *
  68. *    y    =    op 2 ptr
  69. *
  70. *        Note: "tos" stands for top of stack
  71. *        The stack looks the same for DDIVU once all the
  72. *        work space has been allocated.
  73. *
  74. mul_loop:
  75.     clc            reset carry bit...
  76.     brclr    reslo32+lo+1,%x,#1,skip
  77.     ldd    lo,%y        add to result low of op 2
  78.     addd    res+lo,%x    result word 1
  79.     std    res+lo,%x    new result word 1
  80.     ldd    hi,%y        add to result hi of op 2
  81.     adcb    res+hi+1,%x
  82.     adca    res+hi,%x    add to result word 0
  83.     std    res+hi,%x    save in result word 0
  84. skip:
  85.     ror    res+hi,%x
  86.     ror    res+hi+1,%x
  87.     ror    res+lo,%x
  88.     ror    res+lo+1,%x
  89.     ror    reslo32+hi,%x
  90.     ror    reslo32+hi+1,%x
  91.     ror    reslo32+lo,%x
  92.     ror    reslo32+lo+1,%x
  93.     dec    shift,%x    decrement shift count
  94.     bne    mul_loop
  95. *
  96. *    done... clean up the mess...
  97. *
  98.     ldy    op3,%x        get pointer to result
  99.     ldab    #reslo32    remove shift count, high 32 bits of result
  100.     abx            (up to low 32 bits of result)
  101.     txs
  102.     pulx            get result word 2
  103.     stx    hi,%y        store in operand 3
  104.     pulx            get result word 3
  105.     stx    lo,%y        store in operand 3
  106.     pulx            restore x
  107.     rts            done... finally (whew!)
  108. *
  109.     xdef    ddivu
  110. *
  111. *    ddivu    - 32 by 32 divide giving a 32 bit remainder and
  112. *    a 32 bit quotient.  This is an UNSIGNED divide.
  113. *
  114. *    DDIVU divides Operand 1 by Operand 2 storing the remainder
  115. *    and the quotient in Operand 3.  The algorithm takes Operand
  116. *    1 and stores in quotient.  The Y register points to Operand 2.
  117. *    The remainder is initially zero.
  118. *
  119. *    The actual divide is done by shifting the result (remainder and
  120. *    quotient) left 1 bit at a time.  Operand 2 is then subtracted
  121. *    from remainder (Operand 1 shifted in one bit at a time).  If
  122. *    Operand 2 is less than or equal the current remainder (no carry),
  123. *    then the subtraction is completed and low bit of the quotient
  124. *    is set on the next left shift.  If Operand 2 is greater than the
  125. *    current remainder, then the subtraction is undone (through addition)
  126. *    and the low bit of the quotient is cleared on the next left shift.
  127. *
  128. *    Equates:
  129. rem    equ    1    remainder
  130. quo    equ    5    quotient
  131. *
  132. *    note: the equates:
  133. *        shift, savex, rtnPC, op3 are same as DMULU
  134. *
  135. op3_quo    equ    4    offset to operand 3 quotient (result)
  136. *
  137. *    Parameters:
  138. *        Op1 -> ptr to dividend (D register)
  139. *        Op2 -> ptr to divisor (Y register)
  140. *        Op3 -> ptr to result (1st word on stack after return PC)
  141. *
  142. *    Comments:    Operand 1 and Operand 2 are each 32 bits long.
  143. *        Operand 3 (result is 64 bits long).  The hi 32 bits of
  144. *        result is the remainder.  The low 32 bits of the result
  145. *        is the quotient.
  146. *
  147. ddivu    pshx        save x
  148.     xgdy        swap parameters temporarily
  149.     ldx    lo,%y    get operand 1 (dividend)
  150.     pshx        initialize quotient
  151.     ldx    hi,%y
  152.     pshx
  153.     ldx    #0    set remainder to zero initially
  154.     pshx
  155.     pshx
  156.     xgdy        reset parameters
  157.     ldaa    #33    shift count (32 bits plus extra bit in quotient)
  158.     psha
  159.     tsx        point to work area/operands on stack
  160. *    value for 1st shift is not used, not important (low bit for quotient)
  161. *    (because we shift quotient 33 times, 33rd bit goes to bit bucket)
  162. div_loop
  163.     rol    quo+lo+1,%x    save result of previous division
  164.     rol    quo+lo,%x
  165.     rol    quo+hi+1,%x
  166.     rol    quo+hi,%x
  167.     dec    shift,%x    done?
  168.     beq    div_done
  169.     rol    rem+lo+1,%x    update remainder, more to do
  170.     rol    rem+lo,%x
  171.     rol    rem+hi+1,%x
  172.     rol    rem+hi,%x
  173.     ldd    rem+lo,%x
  174.     subd    lo,%y    subtract divisor
  175.     std    rem+lo,%x
  176.     ldd    rem+hi,%x
  177.     sbcb    hi+1,%y        borrow needed bits...
  178.     sbca    hi,%y
  179.     bcc    skip_add    rem >= divisor, can divide
  180. *    undo subtract
  181.     ldd    rem+lo,%x
  182.     addd    lo,%y
  183.     std    rem+lo,%x
  184.     clc            shift in zero into quotient, cannot divide
  185.     bra    div_loop
  186. *    finish subtract...
  187. skip_add:
  188.     std    rem+hi,%x
  189.     sec            shift in one into quotient, can divide
  190.     bra    div_loop
  191. *
  192. div_done:
  193.     ldy    op3,%x        save results
  194.     pula
  195.     pulx
  196.     stx    hi,%y        save hi of remainder
  197.     pulx
  198.     stx    lo,%y        save low of remainder
  199.     pulx
  200.     stx    op3_quo+hi,%y    save hi of quotient
  201.     pulx
  202.     stx    op3_quo+lo,%y    save lo of quotient
  203.     pulx            restore x
  204.     rts            exit stage right (or left...)
  205.     end
  206.